import java.io.*;
import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class TestingCollocation extends DefaultHandler {
  public static String LEXELT_TAG_ = "lexelt";
  public static String LEXELT_ITEM_TAG_ = "item";
  public static String CONTEXT_TAG_ = "context";
  public static String HEAD_TAG_ = "head";
  public static String ANSWER_TAG_ = "answer";
  public static String INSTANCE_TAG_ = "instance";
  public static String INSTANCE_ID_TAG_ = "id";
  public static String SENSE_TAG_ = "senseid";

  private final String testFile_;
  private final String testOutputFile_;
  private CollocationFeature collocFeat_;
  private Training training_;
  private Writer out_;
  private int method_;
  
  private XMLParserState state_ = new XMLParserState(false);
  private WSD wsdObj_;

  public TestingCollocation(String file, String testOutFile, Training training, int method, WSD wsdObj) {
    testFile_ = file;
    testOutputFile_ = testOutFile;
    training_ = training;
    collocFeat_ = training_.getCollocFeat();
    method_ = method;
    wsdObj_ = wsdObj;
    parseTestFile();
  }

  public void parseTestFile() {
    String tmpFile = "tmp.xml";
    try {
      FileWriter writer = new FileWriter(tmpFile);
      FileReader reader = new FileReader(testFile_);
      out_ = new FileWriter(testOutputFile_);
      XMLReader xmlr = XMLReaderFactory.createXMLReader();
      xmlr.setContentHandler(this);
      xmlr.setErrorHandler(this);

      BufferedReader br = new BufferedReader(reader);
      WSD.formatXMLfile(br, writer);
      reader.close();
      reader = new FileReader(tmpFile);

      // Parse the intermediate XML file.
      xmlr.parse(new InputSource(reader));
      out_.close();
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    } catch (SAXParseException spe) {
      StringBuffer sb = new StringBuffer(spe.toString());
      sb.append("\n  Line number: " + spe.getLineNumber());
      sb.append("\nColumn number: " + spe.getColumnNumber());
      sb.append("\n Public ID: " + spe.getPublicId());
      sb.append("\n System ID: " + spe.getSystemId() + "\n");
      System.out.println(sb.toString());
    } catch (SAXException se) {
      System.out.println("loadDOM threw " + se);
      se.printStackTrace(System.out);
    }
  }

  @Override
  public void startElement(String uri, String name, String qName,
      Attributes atts) {
    if (qName.equals(LEXELT_TAG_)) {
      state_.setLexelt(atts.getValue(LEXELT_ITEM_TAG_));
    } else if (qName.equals(HEAD_TAG_)) {
      state_.startHeadTag();
    } else if (qName.equals(INSTANCE_TAG_)) {
      state_.resetForInstance(atts.getValue(INSTANCE_ID_TAG_));
    }
  }

  @Override
  public void endElement(String uri, String name, String qName) {
    if (qName.equals(HEAD_TAG_)) {
      state_.endHeadTag();
    } else if (qName.equals("instance")) {
      String sense = null;
      if (method_ == WSD.COLL_NB_METHOD) {
        sense = collocFeat_.getFeatSense(state_.getLexelt(),
            state_.getPrevNList(), state_.getSuccNList(), wsdObj_);
      } else if(method_ == WSD.COLL_CM_METHOD){
        sense = collocFeat_.getSenseGivenCollFeature_CM(state_.getLexelt(),
            state_.getPrevNList(), state_.getSuccNList(), wsdObj_);
      }
      String str = state_.getLexelt() + " " + state_.getInstanceId() + " " + sense;
      // System.out.println(str);
      try {
        out_.write(str + "\n");
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  public void characters(char ch[], int start, int length) {
    String line = new String(ch, start, length);
    
    collocFeat_.handleCharacters(line, state_);
  }

  @Override
  public void endDocument() throws SAXException {
  }
  
  public CollocationFeature getCollocFeat() {
    return collocFeat_;
  }
}
